package cn.schoolwow.quickdao.module.database.dml.instance.flow.update.service;

import cn.schoolwow.quickdao.domain.database.dml.UpdateType;
import cn.schoolwow.quickdao.domain.entity.Entity;
import cn.schoolwow.quickdao.domain.entity.Property;
import cn.schoolwow.quickdao.module.database.dml.common.domain.GetBatchParametersSupplier;
import cn.schoolwow.quickdao.module.database.dml.common.domain.ManipulationOption;
import cn.schoolwow.quickdao.module.database.dml.instance.flow.update.flow.SetUpdateInstanceParameterFlow;
import cn.schoolwow.quickdao.module.database.dml.instance.flow.update.flow.SetUpdateInstanceStatementFlow;
import cn.schoolwow.quickdao.module.database.dml.instance.flow.update.flow.updateType.SetPropertyListByIdFlow;
import cn.schoolwow.quickdao.module.database.dml.instance.flow.update.flow.updateType.SetPropertyListByUniqueFieldNameFlow;
import cn.schoolwow.quickdao.module.database.dml.instance.flow.update.flow.updateType.SetPropertyListByUniqueKeyFlow;
import cn.schoolwow.quickdao.module.database.parent.flow.executor.ExecuteBatchUpdateConnectionFlow;
import cn.schoolwow.quickflow.domain.FlowContext;
import cn.schoolwow.quickflow.flow.BusinessFlow;

import java.util.ArrayList;
import java.util.List;

public class UpdateInstanceArrayFlow implements BusinessFlow {
    @Override
    public void executeBusinessFlow(FlowContext flowContext) throws Exception {
        setPropertyListByPartColumn(flowContext);
        updateInstanceArray(flowContext);
    }

    @Override
    public String name() {
        return "更新实例数组";
    }

    private void setPropertyListByPartColumn(FlowContext flowContext){
        ManipulationOption manipulationOption = flowContext.checkInstanceData(ManipulationOption.class);
        Entity entity = flowContext.checkData("entity", Entity.class);

        if(manipulationOption.partColumnSet.isEmpty()){
            return;
        }
        List<Property> setPropertyList = new ArrayList<>();
        for(String partColumn: manipulationOption.partColumnSet){
            Property property = entity.getPropertyByFieldNameOrColumnName(partColumn);
            if(null==property){
                throw new IllegalArgumentException("partColum方法指定的字段名不存在!字段名:"+partColumn+",实体类名:"+entity.clazz.getName());
            }
            setPropertyList.add(property);
        }
        flowContext.putTemporaryData("setPropertyList", setPropertyList);
    }

    private void updateInstanceArray(FlowContext flowContext){
        UpdateType updateType = flowContext.checkInstanceData(UpdateType.class);

        switch (updateType){
            case UpdateByUniqueFieldName:{
                flowContext.executeFlowList(new SetPropertyListByUniqueFieldNameFlow());
                flowContext.putTemporaryData("name", "批处理-根据指定唯一字段列表更新实例");
            }break;
            case UpdateByUniqueKey:{
                flowContext.executeFlowList(new SetPropertyListByUniqueKeyFlow());
                flowContext.putTemporaryData("name", "批处理-根据实例唯一约束字段更新实例");
            }break;
            case UpdateById:{
                flowContext.executeFlowList(new SetPropertyListByIdFlow());
                flowContext.putTemporaryData("name", "批处理-根据实例Id字段更新实例");
            }break;
        }

        Object[] instances = (Object[]) flowContext.checkData("instances");
        ManipulationOption manipulationOption = flowContext.checkInstanceData(ManipulationOption.class);

        flowContext.startFlow(new SetUpdateInstanceStatementFlow())
                .next(new ExecuteBatchUpdateConnectionFlow())
                .putTemporaryData("getBatchParametersSupplier",new GetBatchParametersSupplier() {
                    @Override
                    public List<Object> getBatchParameters(Integer index) throws Exception {
                        Object instance = instances[index];
                        flowContext.putTemporaryData("instance", instance);
                        flowContext.executeFlowList(new SetUpdateInstanceParameterFlow());
                        List<Object> parameters = (List<Object>) flowContext.checkData("parameters");
                        return parameters;
                    }
                })
                .putTemporaryData("perBatchCount", manipulationOption.perBatchCount)
                .putTemporaryData("size", instances.length)
                .execute();
    }

}